/*-----------------------------------------------File Info------------------------------------------------
** File Name:               i2c_user.c  
** Last modified date:      20220407
** Last version:            V0.1
** Description:             
**--------------------------------------------------------------------------------------------------------            
** Created date:            20220407
** author:                  YLY
** Version:                 V0.1
** Descriptions:            I2c驱动 
**--------------------------------------------------------------------------------------------------------
*/

/*************************************************************
* 	include 
* 	头文件	
*************************************************************/ 
#include "bspI2C.h"

static volatile tsI2c gtI2c0,gtI2c1;
static tsI2cPara gtParaI2c0,gtParaI2c1;
	
/*	I2C初始化
 *  说明: 	用来发起中断
 *	参数:
*	tepPare:	uint32_t cfg; 				//tsCfgI2c
				uint32_t clkRate;			//100000,400000,1000000
				uint8_t addr7Bit;			//I2C salve 7 bit Address		
				teI2cPort tPort;			//teI2cPort GPIO)
 *	返回: 	NO
 */
void i2cInit(tsCfgI2c *cfg, uint32_t clkRate, uint8_t addr7Bit)	
{
	uint8_t addr8Bit = addr7Bit<<1;//驱动用的8bit地址,先转为8bit

	gpioConfig(&cfg->sclIo);	
	gpioConfig(&cfg->sdaIo);
	
	/*-----------enable the peripheral clock-------------*/		
	rcu_periph_clock_enable(cfg->rcu);	
	i2c_deinit(cfg->i2c);	
	
	i2c_software_reset_config(cfg->i2c, I2C_SRESET_SET);
	bspDelayMs(1);	
	i2c_software_reset_config(cfg->i2c, I2C_SRESET_RESET);	

	/*----------cofigure the I2C0 and I2C1 interfaces-----------*/	
	if(clkRate > 400000)	//快速模式下的占空比
		i2c_clock_config(cfg->i2c, clkRate, I2C_DTCY_16_9);
	else 
		i2c_clock_config(cfg->i2c, clkRate, I2C_DTCY_2);
	/* I2C m2sAddr configure */
	i2c_mode_addr_config(cfg->i2c, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, addr8Bit);	
	/* enable I2C */
	i2c_enable(cfg->i2c);	
	
	/* enable acknowledge */
	i2c_ack_config(cfg->i2c, I2C_ACK_ENABLE);	
	i2c_ackpos_config(cfg->i2c, I2C_ACKPOS_CURRENT);	//I2C_ACKPOS_NEXT	I2C_ACKPOS_CURRENT

	if (cfg->i2c == I2C0)
	{	
		//保存初始化参数，解决异常时，重新复位I2X
		gtParaI2c0.addr7Bit = addr7Bit;
		gtParaI2c0.clkRate = clkRate;

		gtI2c0.intEnSta = false;		/* 考虑到可能用DMA通信,中断使能放在读写函数中 */
#if BSP_MCU_TYPE == BSP_MCU_GD32E23x			
		nvic_irq_enable(I2C0_EV_IRQn, 2);
		nvic_irq_enable(I2C0_ER_IRQn, 1);	
#elif BSP_MCU_TYPE == BSP_MCU_GD32F3x0
		nvic_irq_enable(I2C0_EV_IRQn, 0,1);
		nvic_irq_enable(I2C0_ER_IRQn, 0,2);	
#endif 		
		I2CDEBUG("I2c0InitSuccess,sAddr=%x\r\n",gtParaI2c0.addr7Bit);
	}	
	else if (cfg->i2c == I2C1)//I2C1 使用通道1和2
	{
		//保存初始化参数，解决异常时，重新复位I2X
		gtParaI2c1.addr7Bit = addr7Bit;
		gtParaI2c1.clkRate = clkRate;
		
		gtI2c1.intEnSta = false;
#if BSP_MCU_TYPE == BSP_MCU_GD32E23x			
		nvic_irq_enable(I2C1_EV_IRQn, 2);
		nvic_irq_enable(I2C1_ER_IRQn, 1);
#elif BSP_MCU_TYPE == BSP_MCU_GD32F3x0
		nvic_irq_enable(I2C1_EV_IRQn, 0, 1);
		nvic_irq_enable(I2C1_ER_IRQn, 0, 2);
#endif 				
		I2CDEBUG("I2c1InitSuccess,sAddr=%x\r\n",gtParaI2c1.addr7Bit);
	}
}

static bool resumeI2c(tsCfgI2c *cfg)
{
	tsCfgI2c tCfg = *cfg;
	uint32_t count = 0xff;
	
	/* 尝试复位I2C */		
	rcu_periph_clock_enable(cfg->rcu);	
	i2c_deinit(cfg->i2c);	
	
	rcu_periph_clock_enable(cfg->rcu);
	i2c_software_reset_config(cfg->i2c, I2C_SRESET_SET);
	bspDelayMs(10);
	i2c_software_reset_config(cfg->i2c, I2C_SRESET_RESET);	
	
	/* 关闭I2C */
	rcu_periph_clock_disable(cfg->rcu);

	
	/* 将GPIO初始化为普通IO */	
	tCfg.sclIo.mode = GPIO_MODE_OUTPUT;
	tCfg.sclIo.pull = GPIO_PUPD_PULLUP;
	tCfg.sclIo.otype = GPIO_OTYPE_OD;
	
	tCfg.sdaIo.mode = GPIO_MODE_OUTPUT;
	tCfg.sdaIo.pull = GPIO_PUPD_PULLUP;
	tCfg.sdaIo.otype = GPIO_OTYPE_OD;
	
	gpioConfig(&tCfg.sclIo);
	gpioConfig(&tCfg.sdaIo);
	do
	{		
		gpioWrite(&tCfg.sclIo,0);		
		
		bspDelayMs(20);
		gpioWrite(&tCfg.sdaIo,0);
		
		bspDelayMs(20);
		gpioWrite(&tCfg.sclIo,1);	
		
		bspDelayMs(20);
		gpioWrite(&tCfg.sdaIo,1);
		
		bspDelayMs(20);	

		if(count-- == 0) 
		{
			if(cfg->i2c == I2C0)
				I2CERR("resume I2c0 fail\r\n");
			else
				I2CERR("resume I2c1 fail\r\n");
			return false;
		}
	}while((!gpioGetInput(&tCfg.sdaIo)) || (!gpioGetInput(&tCfg.sclIo)));
	
	if(cfg->i2c == I2C0)
		I2CERR("resume I2c0 success\r\n");
	else
		I2CERR("resume I2c1 success\r\n");
	return true;
}

void i2cReinit(tsCfgI2c *cfg)	
{
	resumeI2c(cfg);
	
	if(cfg->i2c == I2C0)	
	{
		I2CERR("i2c0Reinit\r\n");	
		i2cInit(cfg, gtParaI2c0.clkRate, gtParaI2c0.addr7Bit);
	}
	else if(cfg->i2c == I2C1)	
	{	
		I2CERR("i2c1Reinit\r\n");
		i2cInit(cfg, gtParaI2c1.clkRate, gtParaI2c1.addr7Bit);
	}
}


/*	I2C中断使能
 *  说明: 	
 *	参数:cfg->i2c I2Cx
 *	返回: 	NO
 */
void i2cInterruptEnable(tsCfgI2c *cfg)
{
	if(cfg->i2c == I2C0)
	{
		if(gtI2c0.intEnSta == true)
			return;
		
		gtI2c0.intEnSta = true;
		//I2CDEBUG("I2C0InterruptEnable\n");
	}
	else if(cfg->i2c == I2C1)
	{
		if(gtI2c1.intEnSta == true)
			return;	
		
		gtI2c1.intEnSta = true;
		//I2CDEBUG("I2C1InterruptEnable\n");
	}

	/* enable the I2C0 interrupt */
	i2c_interrupt_enable(cfg->i2c, I2C_INT_ERR);	//当BERR、 LOSTARB、 AERR、 OUERR、 PECERR、 SMBTO或SMBALT标志位生效时产生中断。
	i2c_interrupt_enable(cfg->i2c, I2C_INT_BUF);	//如果EVIE =1，当TBE = 1或RBNE = 1时产生中断
	i2c_interrupt_enable(cfg->i2c, I2C_INT_EV);		//SBSEND、 ADDSEND、 ADD10SEND、 STPDET或BTC标志位有效或当BUFIE=1时TBE=1或RBNE=1时产生中断。
}

/*	I2C中断禁止
 *  说明: 	
 *	参数:cfg->i2c I2Cx
 *	返回: 	NO
 */
void i2cInterruptDisable(tsCfgI2c *cfg)
{
	if(cfg->i2c == I2C0)
	{
		if(gtI2c0.intEnSta == false)
			return;
		gtI2c0.intEnSta = false;
		//I2CDEBUG("I2C0InterruptDisble\n");
	}
	else if(cfg->i2c == I2C1)
	{
		if(gtI2c1.intEnSta == false)
			return;		
		gtI2c1.intEnSta = false;
		//I2CDEBUG("I2C1InterruptDisble\n");
	}	
	/* enable the I2C0 interrupt */
	i2c_interrupt_disable(cfg->i2c, I2C_INT_ERR);	//当BERR、 LOSTARB、 AERR、 OUERR、 PECERR、 SMBTO或SMBALT标志位生效时产生中断。
	i2c_interrupt_disable(cfg->i2c, I2C_INT_BUF);	//如果EVIE =1，当TBE = 1或RBNE = 1时产生中断
	i2c_interrupt_disable(cfg->i2c, I2C_INT_EV);		//SBSEND、 ADDSEND、 ADD10SEND、 STPDET或BTC标志位有效或当BUFIE=1时TBE=1或RBNE=1时产生中断。
}

/**    主机发送数据
* 参数:
* 		cfg->i2c:I2C0,I2C1
*  		m2sAddr:	从机的7位地址  
* 		pBuf: 数据BUF
*		size:	BUF大小
*		tCb:	状态回调
* 返回: FAIL OR SUCCESS
**/ 
uint8_t i2cMasterWrite(tsCfgI2c *cfg, uint8_t m2sAddr, 
						 uint8_t *pBuf, uint32_t size, 
						 ptI2C_Callback tCb)
{
	uint8_t i = 0;
	volatile tsI2c *ptI2c;
	
	if(cfg->i2c == I2C0)		
		ptI2c = &gtI2c0;
	else
		ptI2c = &gtI2c1;

	m2sAddr <<= 1;
	
	/* the master waits until the I2C bus is idle */
	while(i2c_flag_get(cfg->i2c, I2C_FLAG_I2CBSY))
	{
		bspDelayMs(10);
		if(++i > I2CBSY_WAIT_MAX_TIME)
		{			
			I2CERR("I2CmWrBsyTo\r\n");
			if(tCb)
				tCb(I2C_BUS_ERROR,0,0);
			while(1);	//等待看门狗重启单片机
		}
		I2C_WDT();
		
		if(i > I2CBSY_RESET_TIME)
		{
			I2CERR("I2CmWrBsy\r\n");
			i2cReinit(cfg);
		}				
	}
	
	i2cInterruptDisable(cfg);								//关闭中断	
	
	ptI2c->eMastOrSlave = I2C_MAST;	
	ptI2c->eWrOrRe = I2C_WRITE;
	ptI2c->m2sAddr = m2sAddr;				
	ptI2c->pWr = pBuf;
	ptI2c->tWrCb = tCb;
	ptI2c->wrLen = size;	
	ptI2c->wrCnt = 0;
	
	i2cInterruptEnable(cfg);				//打开中断	
	i2c_ack_config(cfg->i2c, I2C_ACK_ENABLE);		
	i2c_start_on_bus(cfg->i2c);
	return true;
}

/**    主机接收数据
* 参数:
* 		cfg->i2c:I2C0,I2C1
*  		m2sAddr:	从机的7位地址  
* 		pBuf: 数据BUF
*		size:	BUF大小
*		tCb:	状态回调
* 返回: FAIL OR SUCCESS
**/ 
uint8_t i2cMasterRead(tsCfgI2c *cfg, uint8_t m2sAddr, uint8_t *pBuf, uint32_t size, ptI2C_Callback tCb)
{
	uint8_t i=0;
	volatile tsI2c *ptI2c;
	
	if(cfg->i2c == I2C0)		
		ptI2c = &gtI2c0;
	else
		ptI2c = &gtI2c1;
	
	m2sAddr <<= 1;
	
	/* the master waits until the I2C bus is idle */
	while(i2c_flag_get(cfg->i2c, I2C_FLAG_I2CBSY))
	{
		bspDelayMs(10);
		if(++i > I2CBSY_WAIT_MAX_TIME)
		{
			I2CERR("I2CmReBsyTo\r\n");
			if(tCb)
				tCb(I2C_BUS_ERROR,0,0);
			while(1);	//等待看门狗重启单片机
		}
		I2C_WDT();
		if(i > I2CBSY_RESET_TIME)
		{
			I2CERR("I2CmReBsy\r\n");
			i2cReinit(cfg);
		}				
	}
	
	i2cInterruptDisable(cfg);								//关闭中断	

	ptI2c->eMastOrSlave = I2C_MAST;	
	ptI2c->eWrOrRe = I2C_READ;
	ptI2c->m2sAddr = m2sAddr;			//设置数据
	ptI2c->tReCb = tCb;		
	ptI2c->pRe = pBuf;
	ptI2c->reLen = size;	
	ptI2c->reCnt = 0;
	
	i2cInterruptEnable(cfg);				//打开中断
	i2c_ack_config(cfg->i2c, I2C_ACK_ENABLE);
	i2c_start_on_bus(cfg->i2c);
	return true;
}

/**    从机发送数据
* 参数:
* 		cfg->i2c:I2C0,I2C1
*  		m2sAddr:	从机的7位地址  
* 		pBuf: 数据BUF
*		size:	BUF大小
*		tCb:	状态回调
* 返回: FAIL OR SUCCESS
**/ 
uint8_t i2cSlaveWrite(tsCfgI2c *cfg, uint8_t *pBuf, uint32_t size, ptI2C_Callback tCb)
{
	uint8_t i=0;
	volatile tsI2c *ptI2c;
	
	if(cfg->i2c == I2C0)		
		ptI2c = &gtI2c0;
	else
		ptI2c = &gtI2c1;
	
	/* the master waits until the I2C bus is idle */
	while(i2c_flag_get(cfg->i2c, I2C_FLAG_I2CBSY))
	{
		bspDelayMs(10);
		if(++i > I2CBSY_WAIT_MAX_TIME)
		{
			I2CERR("I2CsWrBsyTo\r\n");
			if(tCb)
				tCb(I2C_BUS_ERROR,0,0);
			while(1);	//等待看门狗重启单片机
		}
		I2C_WDT();
		if(i > I2CBSY_RESET_TIME)
		{
			I2CERR("I2CsWrBsy\r\n");
			i2cReinit(cfg);
		}				
	}
	
	i2cInterruptDisable(cfg);								//关闭中断	

	ptI2c->eMastOrSlave = I2C_SLAVE;			
	ptI2c->eWrOrRe = I2C_WRITE;
	ptI2c->tWrCb = tCb;
	ptI2c->pWr = pBuf;
	ptI2c->wrLen = size;	
	ptI2c->wrCnt = 0;
	
	i2c_ack_config(cfg->i2c, I2C_ACK_ENABLE);
	i2cInterruptEnable(cfg);				//打开中断		
	return true;
}

/**    从机接收数据
* 参数:
* 		cfg->i2c:I2C0,I2C1
*  		m2sAddr:	从机的7位地址  
* 		pBuf: 数据BUF
*		size:	BUF大小
*		tCb:	状态回调
* 返回: FAIL OR SUCCESS
**/ 
uint8_t i2cSlaveRead(tsCfgI2c *cfg, uint8_t *pBuf, uint32_t size, ptI2C_Callback tCb)
{
	uint8_t i=0;
	volatile tsI2c *ptI2c;
	
	if(cfg->i2c == I2C0)		
		ptI2c = &gtI2c0;
	else
		ptI2c = &gtI2c1;
	
	/* the master waits until the I2C bus is idle */
	while(i2c_flag_get(cfg->i2c, I2C_FLAG_I2CBSY))
	{
		bspDelayMs(10);
		if(++i > I2CBSY_WAIT_MAX_TIME)
		{
			I2CDEBUG("I0sReBsyTo\r\n");
			if(tCb)
				tCb(I2C_BUS_ERROR,0,0);
			while(1);	//等待看门狗重启单片机
		}
		I2C_WDT();
		if(i > I2CBSY_RESET_TIME)
		{
			I2CERR("I0sReBsy\r\n");
			i2cReinit(cfg);
		}			
	}
	i2cInterruptDisable(cfg);								//关闭中断	

	ptI2c->eMastOrSlave = I2C_SLAVE;		
	ptI2c->eWrOrRe = I2C_READ;
	ptI2c->tReCb = tCb;
	ptI2c->pRe = pBuf;
	ptI2c->reLen = size;	
	ptI2c->reCnt = 0;
	
	i2c_ack_config(cfg->i2c, I2C_ACK_ENABLE);
	i2cInterruptEnable(cfg);				//打开中断			

	return true;
}




/*
I2C_INT_EV:					//SBSEND、 ADDSEND、 ADD10SEND、 STPDET或BTC标志位有效或当BUFIE=1时TBE=1或RBNE=1时产生中断。
	I2C_INT_FLAG_SBSEND		//主机发起起始成功，在这个中断后应该是装从机地址
	I2C_INT_FLAG_ADDSEND    //主机发起地址
    I2C_INT_FLAG_BTC        //数据发送完成
	I2C_INT_FLAG_ADD10SEND  //主机发送10位地址
	I2C_INT_FLAG_STPDET     //从机模式检测到停止

I2C_INT_BUF:				//如果EVIE =1，当TBE = 1或RBNE = 1时产生中断
	I2C_INT_FLAG_TBE        //发送缓冲区空  
    I2C_INT_FLAG_RBNE      	//接收到数据 

I2C_INT_ERR:				//当BERR、 LOSTARB、 AERR、 OUERR、 PECERR、 SMBTO或SMBALT标志位生效时产生中断。
    I2C_INT_FLAG_BERR     	//总线错位
    I2C_INT_FLAG_LOSTARB    //仲裁失败
    I2C_INT_FLAG_AERR      	//NACK 没有时到ACK
    I2C_INT_FLAG_OUERR 		//超时
    I2C_INT_FLAG_PECERR     //CRC错误
    I2C_INT_FLAG_SMBTO      //SMBus 模式下总线超时
    I2C_INT_FLAG_SMBALT     //SMBus 警报
	
I2C_INT_TFF: 	//txframe fall interrupt enable	
    I2C_INT_FLAG_TFF      	//txframe fall interrupt flag 
	
I2C_INT_TFR: 	//txframe rise interrupt enable	
    I2C_INT_FLAG_TFR       //txframe rise interrupt  flag 
	
I2C_INT_RFF: 	//rxframe fall interrupt enable	
    I2C_INT_FLAG_RFF        // rxframe fall interrupt flag 
	
I2C_INT_RFR: 	//rxframe rise interrupt enable		
    I2C_INT_FLAG_RFR        //rxframe rise interrupt flag
*/
	
static void i2cEvIqrHandler(uint32_t i2c_periph)
{
	volatile tsI2c *ptI2c;
	teFeedback eFeedback;
	
	if(i2c_periph == I2C0)	
	{		
		ptI2c = &gtI2c0;
		I2CINTDBG("\r\n0v");
	}
	else
	{
		ptI2c = &gtI2c1;
		I2CINTDBG("\r\n1v");
	}	

	/**	ReReTo
	 *	I2C_INT_EV	SBSEND、 ADDSEND、 ADD10SEND、 
	 *	STPDET或BTC标志位有效
	 *	或当BUFIE=1时TBE=1或RBNE=1时产生中断。
	*/
    if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_SBSEND))	//主机发起起始成功
	{
		I2CINTDBG(",STA");	
		if(ptI2c->eWrOrRe == I2C_READ)
		{
			i2c_master_addressing(i2c_periph, ptI2c->m2sAddr, I2C_RECEIVER);
		}
		else if(ptI2c->eWrOrRe == I2C_WRITE)
		{
			i2c_master_addressing(i2c_periph, ptI2c->m2sAddr, I2C_TRANSMITTER);
		}	
		ptI2c->stopSend = false;
		ptI2c->cbSta = false;	//主机
		i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_SBSEND); //写ADDR后自动清除	
    }
	
	if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_ADDSEND))	//地址发送和接收成功
	{	
		I2CINTDBG(",ad");
		ptI2c->cbSta = false;	//从机
		if(i2c_flag_get(i2c_periph,I2C_FLAG_MASTER))	//主机模式
		{
			I2CINTDBG("/M");
			ptI2c->eMastOrSlave = I2C_MAST;
		}
		else 
		{
			I2CINTDBG("/S");
			ptI2c->eMastOrSlave = I2C_SLAVE;
		}
		
		if(i2c_flag_get(i2c_periph,I2C_FLAG_TR))	//读写模式
		{
			I2CINTDBG("/W/%d",ptI2c->wrLen);
			ptI2c->eWrOrRe = I2C_WRITE;
		}
		else 
		{
			I2CINTDBG("/R/%d",ptI2c->reLen);
			ptI2c->eWrOrRe = I2C_READ;
		}
		
		ptI2c->wrCnt = 0;
		ptI2c->reCnt = 0;
		
		//接收采用方案A
		if(ptI2c->eWrOrRe == I2C_READ)	
		{
			if(ptI2c->eMastOrSlave == I2C_MAST)	//主机模式,需要控制接受数据
			{
				if(ptI2c->reLen == 1)	//只接收1位数据,接下来发NACK,和停止位
				{
					I2CINTDBG("/NA");
					i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
					if(!ptI2c->stopSend)
					{
						I2CINTDBG("/stp");					
						ptI2c->stopSend = true;
						i2c_stop_on_bus(i2c_periph);
					}
				}
			}
			else	//从机模式,打开ACK
			{
				I2CINTDBG(",A");
				i2c_ack_config(i2c_periph, I2C_ACK_ENABLE);
			}
		}			
		i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_ADDSEND);			
    }
	
	if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_ADD10SEND))//主机发送10位地址,常规的I2C都是7bit地址10bit暂时用不上
	{
		I2CINTDBG(",ad10");
		i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_ADD10SEND);	
    }
	
	/**	
	 *	I2C_INT_BUF	如果EVIE =1，当TBE = 1或RBNE = 1时产生中断
	*/	
	if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_TBE))  		//发送缓冲区空,在这里装数据后自动清除  
	{
		I2CINTDBG(",TB/%d",ptI2c->wrCnt);
		if(ptI2c->wrCnt < ptI2c->wrLen)
		{
			i2c_data_transmit(i2c_periph, ptI2c->pWr[ptI2c->wrCnt++]);		
		}
		else
		{
			i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_TBE);		//装数据自动清除		 
		}
		if(ptI2c->eMastOrSlave == I2C_SLAVE)	//从机必需在此处回调,主机需要等I2C_INT_FLAG_BTC置位才回调
		{
			if(ptI2c->wrCnt == ptI2c->wrLen)	//数据发送结束
			{
				eFeedback = I2C_SUCCESS;		//成功
				if(ptI2c->tWrCb && !ptI2c->cbSta)						//回调
				{
					ptI2c->cbSta = true;
					ptI2c->tWrCb(eFeedback, ptI2c->pWr, ptI2c->wrCnt);	
				}
			}	
		}		
    }
	
	if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_RBNE)) 	//接收到数据,读数据自动清除	
	{
		I2CINTDBG(",RB/%d",ptI2c->reCnt);

		if(ptI2c->reCnt < ptI2c->reLen)
		{
			ptI2c->pRe[ptI2c->reCnt++] = i2c_data_receive(i2c_periph);	/* read a data byte from I2C_DATA*/	
		}
		else
		{
			i2c_data_receive(i2c_periph);
			if(ptI2c->eMastOrSlave == I2C_MAST)
			{	
				i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
				if(!ptI2c->stopSend)
				{
					I2CINTDBG("/stp1");					
					ptI2c->stopSend = true;
					i2c_stop_on_bus(i2c_periph);
				}
			}	
		}
		
		if(ptI2c->reCnt == ptI2c->reLen-1)	//最后一个字节不发NACK,
		{	
			i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
			if(ptI2c->eMastOrSlave == I2C_MAST)
			{	
				if(!ptI2c->stopSend)
				{
					I2CINTDBG("/stp1");					
					ptI2c->stopSend = true;
					i2c_stop_on_bus(i2c_periph);
				}
			}									
		}		
		else if(ptI2c->reCnt == ptI2c->reLen)//数据接收完成
		{	
			eFeedback = I2C_SUCCESS;		//成功
			if(ptI2c->tReCb && !ptI2c->cbSta)						//回调
			{
				ptI2c->cbSta = true;
				ptI2c->tReCb(eFeedback, ptI2c->pRe, ptI2c->reCnt);	
			}
			
			if(ptI2c->eMastOrSlave == I2C_MAST)
			{	
				if(!ptI2c->stopSend)
				{
					I2CINTDBG("/stp2");					
					ptI2c->stopSend = true;
					i2c_stop_on_bus(i2c_periph);
				}
			}	
		}

		i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_RBNE);
    }
	
	if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_STPDET))	//从机模式检测到停止
	{
		I2CINTDBG(",STP");
		if(ptI2c->eWrOrRe == I2C_READ)			//从机读
		{
			eFeedback = I2C_SUCCESS;			//成功
			if(ptI2c->tReCb && !ptI2c->cbSta)						//回调
			{
				ptI2c->cbSta = true;
				ptI2c->tReCb(eFeedback, ptI2c->pRe, ptI2c->reCnt);	
			}		
		}	
		else	//从机写
		{
			if(ptI2c->wrCnt == ptI2c->wrLen)
				eFeedback = I2C_SUCCESS;		//成功
			else
				eFeedback = I2C_FAIL;			//失败
			
			if(ptI2c->tWrCb && !ptI2c->cbSta)						//回调
			{
				ptI2c->cbSta = true;
				ptI2c->tWrCb(eFeedback, ptI2c->pWr, ptI2c->wrCnt);	
			}
		}	
		i2c_ack_config(i2c_periph, I2C_ACK_ENABLE);
		i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_STPDET);
    }	
	
	if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_BTC)) 	//字节发送结束,数据发送完成,回调(发数据时先收到I2C_INT_FLAG_TBE发送缓冲区空,再收到 I2C_INT_FLAG_BTC)
	{	
		//在发送模块下可以看成最后一个字节发送完成,在接收模块下没有及时读取数据,表示移位寄存器和接收缓冲区都有数据
		I2CINTDBG(",BT");
		if(ptI2c->eWrOrRe == I2C_WRITE)	//在发送模块下,缓冲区和移位寄存器均无数据
		{		
			if(ptI2c->wrCnt == ptI2c->wrLen)
			{		
				if(!ptI2c->stopSend)
				{
					I2CINTDBG("/STP");					
					ptI2c->stopSend = true;
					i2c_stop_on_bus(i2c_periph);					
				}	
				eFeedback = I2C_SUCCESS;			//成功
				if(ptI2c->tWrCb && !ptI2c->cbSta)						//回调
				{
					ptI2c->cbSta = true;
					ptI2c->tWrCb(eFeedback, ptI2c->pWr, ptI2c->wrCnt);	
				}
					
			}			
		}
		else	//在接收模块下没有及时读取数据,
		{
			i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
		}
		i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_BTC);
    }	
	I2CINTDBG("\r\n");
}
/*!
    \brief      this function handles I2C0 event interrupt request exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void I2C0_EV_IRQHandler(void)
{
	i2cEvIqrHandler(I2C0);
}

void I2C1_EV_IRQHandler(void)
{
	i2cEvIqrHandler(I2C1);
}


static void i2cErIqrHandelr(uint32_t i2c_periph)
{
	teFeedback eFeedback;
	volatile tsI2c *ptI2c;
	
	if(i2c_periph == I2C0)
	{
		I2CINTDBG("\r\n0e");			
		ptI2c = &gtI2c0;
	}
	else
	{
		I2CINTDBG("\r\n1e");	
		ptI2c = &gtI2c1;
	}
	

    if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_AERR))				//NACK 没有时到ACK
	{
		I2CINTDBG(",NA");		
        i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_AERR);
    }
	
    if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_PECERR))		//CRC错误
	{	
		I2CINTDBG(",CRC");
        i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_PECERR);		
    }
	
    if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_OUERR))		//超时
	{	
		I2CINTDBG(",OU");
        i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_OUERR);
    }
	
    if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_LOSTARB))		//仲裁失败
	{	
		I2CINTDBG(",LOSTARB");
        i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_LOSTARB);
    }
	
    if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_BERR))		//总线错位
	{
		I2CINTDBG(",BUS");
        i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_BERR);
    }	
	
    if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_SMBALT))		//SMBus 警报
	{	
		I2CINTDBG(",SMBUS");
        i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_SMBALT);
    }
	
    if(i2c_interrupt_flag_get(i2c_periph, I2C_INT_FLAG_SMBTO))		//SMBus 模式下总线超时
	{	
		I2CINTDBG(",SMBTO");		
        i2c_interrupt_flag_clear(i2c_periph, I2C_INT_FLAG_SMBTO);
    }	
	/* 错误发送停止信号 */
	if(ptI2c->eMastOrSlave == I2C_MAST)//主机模式发停止信号
	{
		if(!ptI2c->stopSend)
		{
			I2CINTDBG(",STP");			
			ptI2c->stopSend = true;
			
			eFeedback = I2C_FAIL;			//成功
			if(ptI2c->eWrOrRe == I2C_WRITE)	//在发送模块下,缓冲区和移位寄存器均无数据
			{
				if(ptI2c->tWrCb && !ptI2c->cbSta)						//回调
				{
					ptI2c->cbSta = true;
					ptI2c->tWrCb(eFeedback, ptI2c->pWr, ptI2c->wrCnt);	
				}
			}	
			else
			{	
				if(ptI2c->tReCb && !ptI2c->cbSta)						//回调
				{
					ptI2c->cbSta = true;
					ptI2c->tReCb(eFeedback, ptI2c->pRe, ptI2c->reCnt);	
				}
			}			
			i2c_stop_on_bus(i2c_periph);
		}
	}
	I2CINTDBG("\r\n");		
}
/*!
    \brief      this function handles I2C0 error interrupt request exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void I2C0_ER_IRQHandler(void)
{	
	i2cErIqrHandelr(I2C0);
}
void I2C1_ER_IRQHandler(void)
{
	i2cErIqrHandelr(I2C1);
}